package com.fundamental.classEx.classloader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class FuncLoader extends ClassLoader {

    private static FuncLoader instance;

    private FuncLoader(String path,String... classNames){

        for(String className : classNames) {
            String allClassName = className + ".class";
            String allPath = path + "/" + allClassName;
            File file = new File(allPath);

            try {
                FileInputStream fis = new FileInputStream(file);
                byte[] bytes = new byte[(int) file.length()];

                fis.read(bytes);
                fis.close();


                String defineName = className.replace('/', '.');
                defineClass(defineName, bytes, 0, bytes.length);


            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }


    }


    public static void reloadClass(){
        synchronized (FuncLoader.class) {
            String className = "com/fundamental/classEx/classloader/Fun1";
            //String className = "com/fundamental/classEx/classloader/Func";
            instance = new FuncLoader("E:/javafundamental/target/production/javafundamental", className);
            try {
                //Class c = Class.forName(className.replace('/', '.'));
                Class c = instance.loadClass(className.replace('/', '.'),true);
                Object obj = c.newInstance();
                Method m = c.getMethod("doWhile");
                //System.out.println("加载中");
                //m.invoke(obj);
                //System.out.println("重新load后"+newF.a);
                Test.func = null;    //这里注释掉以后热更不生效，因为此时老类和新类的信息都在，如果不替换对象，老类是不会更新的。
                Test.func = (Func) obj;//TODO 为啥fun1会报错，老的信息与新的信息不同导致了冲突

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }/* catch (InvocationTargetException e) {
                e.printStackTrace();
            }*/
        }
    }

    public static void main(String[] args){
        reloadClass();
    }



}
